<?php

declare(strict_types = 1);

namespace Application\Queue;

use Swoole\Coroutine\Http\Client as WebSocketClient;

/**
 * Class Client
 *
 * @package Application\Chat
 */
class Client
{
    /** @var string $host */
    protected string $host;
    /** @var int $port */
    protected int $port;

    /** @var WebSocketClient $webSocketClient */
    protected WebSocketClient $webSocketClient;

    /**
     * Client constructor.
     *
     * @param string $host
     * @param int $port
     * @throws \Exception
     */
    public function __construct(string $host, int $port)
    {
        $this->host = $host;
        $this->port = $port;

        $this->initialize();
    }

    /**
     * Initialization.
     *
     * @throws \Exception
     */
    protected function initialize()
    {
        $this->webSocketClient = new WebSocketClient($this->host, $this->port, false);
        $this->webSocketClient->set([
            'keep_alive' => true
        ]);
        if (!$this->webSocketClient->upgrade('/')) {
            throw new \Exception('Initialization failed.');
        }
    }

    /**
     * Close.
     */
    public function close()
    {
        $this->webSocketClient->close();
    }

    /**
     * Dispatch message.
     *
     * @param string $message
     * @param string $queue
     * @param callable|null $failureCallback
     * @return bool
     */
    public function dispatch(string $message, string $queue, callable $failureCallback = null): bool
    {
        $result = $this->webSocketClient->push(new Message($queue, $message))
            && $this->webSocketClient->recv()->data === 'ack';

        if ($result) return true;

        if (!is_null($failureCallback))  $failureCallback();

        return false;
    }
}